package.cpath = "luaclib/?.so;3rd/lua-rand/?.so;3rd/lua-cjson/?.so;shao/?.lua;"
local skynet = require "skynet"
local json   = require "cjson"
local rand   = require "rand"


function in_array(arr, obj)
	for i, v in ipairs(arr) do
		if v == obj then return true end
	end
	return false
end

function not_in_insert_array(arr, obj)
	for i, v in ipairs(arr) do
		if v == obj then return end
	end
	table.insert(arr,obj)
end

function class(classname, super)
    local superType = type(super)
    local cls

    if superType ~= "function" and superType ~= "table" then
        superType = nil
        super = nil
    end

    if superType == "function" or (super and super.__ctype == 1) then
        -- inherited from native C++ Object
        cls = {}

        if superType == "table" then
            -- copy fields from super
            for k,v in pairs(super) do cls[k] = v end
            cls.__create = super.__create
            cls.super    = super
        else
            cls.__create = super
            cls.ctor = function() end
        end

        cls.__cname = classname
        cls.__ctype = 1

        function cls.new(...)
            local instance = cls.__create(...)
            -- copy fields from class to native object
            for k,v in pairs(cls) do instance[k] = v end
            instance.class = cls
            instance:ctor(...)
            return instance
        end

    else
        -- inherited from Lua Object
        if super then
            cls = {}
            setmetatable(cls, {__index = super})
            cls.super = super
        else
            cls = {ctor = function() end}
        end

        cls.__cname = classname
        cls.__ctype = 2 -- lua
        cls.__index = cls

        function cls.new(...)
            local instance = setmetatable({}, cls)
            instance.class = cls
            instance:ctor(...)
            return instance
        end
    end

    return cls
end

-- deep copy
function clone(object)
    local lookup_table = {}
    local function _copy(object)
        if type(object) ~= "table" then
            return object
        elseif lookup_table[object] then
            return lookup_table[object]
        end
        local new_table = {}
        lookup_table[object] = new_table
        for key, value in pairs(object) do
            new_table[_copy(key)] = _copy(value)
        end
        return setmetatable(new_table, getmetatable(object))
    end
    return _copy(object)
end

function dump_table( dt, floor, max_floor, tag ) 
	tag = tag and tag or ""
	if not floor then 
		floor = 0 
	end 
	if not max_floor then 
		max_floor = 1 
	end 
	if floor > max_floor then 
		return 
	end 

	local logstr = ""
	for i=1,floor do
		logstr = logstr.."   "
	end

	for k, v in pairs( dt ) do 
		skynet.error(tag .. " " .. string.format(logstr.."%s = %s", k, tostring(v) ) ) 
		if type(v) == "table" then 
		 	dump_table( v, floor + 1, max_floor ) 
		end 
	end 
end 

function table.removebyvalue(array, value, removeall)
    local c, i, max = 0, 1, #array
    while i <= max do
        if array[i] == value then
            table.remove(array, i)
            c = c + 1
            i = i - 1
            max = max - 1
            if not removeall then break end
        end
        i = i + 1
    end
    return c
end
function echobject(obj)
	print("------------------show----------------:",json.encode(obj))
end

function getmicrosecond()
	return rand.getmicrosecond()
end
--------------------------------------------------------
-- skynet timer interface
--------------------------------------------------------
local max_id = 0
local timer_ids = {}
function add_skynet_timer(sec,func)
    max_id = max_id + 1
    local id = max_id
    timer_ids[id] = true
    local wrapper = function()
        if not timer_ids[id] then
            return
        end
        timer_ids[id] = nil
        func()
    end
    skynet.timeout(sec*100,wrapper)
    return id
end

function add_skynet_timer2(sec,func)
    max_id = max_id + 1
    local id = max_id
    timer_ids[id] = true
	local function wrapper()
		skynet.timeout(sec * 100, function() 
			if not timer_ids[id] then
				return
			end
			--timer_ids[id] = nil
			func()
			wrapper()
		end)
	end
	wrapper()
    return id
end

function add_skynet_timer3(sec, func, times)
    max_id = max_id + 1
    local id = max_id
    timer_ids[id] = true
	local exec_times = times
	local cur_times = 1
	local function wrapper()
		skynet.timeout(sec * 100, function() 
			if not timer_ids[id] then
				return
			end
			func()
			cur_times = cur_times + 1
			if cur_times >= exec_times then 
				timer_ids[id] = nil
			end
			wrapper()
		end)
	end
	func()
	wrapper()
    return id
end

function del_skynet_timer(id)
    timer_ids[id] = nil
end

--组合
function return_combination(list_arr,num)
    local tmp_arr = {}
    function combination(arr,nCount,resultArr,head)
        head = head or 1
        resultArr = resultArr or {}
        if (#resultArr == nCount )  then
            --组合选的结果出来
            table.insert(tmp_arr,clone(resultArr) )
            -- print(table.concat(resultArr,","))
        else
            for  i = head,#arr do
                if(#resultArr < nCount  ) then    
                    table.insert(resultArr,arr[i])
                    combination(arr,nCount,resultArr,i + 1)
                    --回溯还原
                    table.remove(resultArr)
                end
            end         
        end 
    end
    combination(list_arr,num)
    return tmp_arr
end


--截取中英混合的UTF8字符串，endIndex可缺省
function SubStringUTF8(str, startIndex, endIndex)
    if startIndex < 0 then
        startIndex = SubStringGetTotalIndex(str) + startIndex + 1;
    end

    if endIndex ~= nil and endIndex < 0 then
        endIndex = SubStringGetTotalIndex(str) + endIndex + 1;
    end

    if endIndex == nil then 
        return string.sub(str, SubStringGetTrueIndex(str, startIndex));
    else
        return string.sub(str, SubStringGetTrueIndex(str, startIndex), SubStringGetTrueIndex(str, endIndex + 1) - 1);
    end
end

--获取中英混合UTF8字符串的真实字符数量
function SubStringGetTotalIndex(str)
    local curIndex = 0;
    local i = 1;
    local lastCount = 1;
    repeat 
        lastCount = SubStringGetByteCount(str, i)
        i = i + lastCount;
        curIndex = curIndex + 1;
    until(lastCount == 0);
    return curIndex - 1;
end

function SubStringGetTrueIndex(str, index)
    local curIndex = 0;
    local i = 1;
    local lastCount = 1;
    repeat 
        lastCount = SubStringGetByteCount(str, i)
        i = i + lastCount;
        curIndex = curIndex + 1;
    until(curIndex >= index);
    return i - lastCount;
end

--返回当前字符实际占用的字符数
function SubStringGetByteCount(str, index)
    local curByte = string.byte(str, index)
    local byteCount = 1;
    if curByte == nil then
        byteCount = 0
    elseif curByte > 0 and curByte <= 127 then
        byteCount = 1
    elseif curByte>=192 and curByte<=223 then
        byteCount = 2
    elseif curByte>=224 and curByte<=239 then
        byteCount = 3
    elseif curByte>=240 and curByte<=247 then
        byteCount = 4
    end
    return byteCount;
end

--字符串切割
function split( str,reps )
    local resultStrList = {}
    string.gsub(str,'[^'..reps..']+',function ( w )
        table.insert(resultStrList,w)
    end)
    return resultStrList
end 